package kr.co.bettersoft.pushchat.activity;

import static kr.co.bettersoft.pushchat.common.CommonConstant.SENDER_ID;

import java.util.List;

import kr.co.bettersoft.pushchat.activity.R;
import kr.co.bettersoft.pushchat.common.CommonConstant;
import kr.co.bettersoft.pushchat.common.PushChatRest;
import kr.co.bettersoft.pushchat.domain.ChatMember;
import kr.co.bettersoft.pushchat.domain.PushChatMember;

import android.app.ActivityManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Vibrator;
import android.support.v4.app.NotificationCompat.Builder;
import android.util.Log;

import com.google.android.gcm.GCMBaseIntentService;
/**
 * GCM 푸시 관련 서비스.
 *  GCM을 등록하고, 등록되면 서버에 GCM 아이디를 저장하며
 *   서버에서 날아오는 푸시 메시지를 처리한다.
 * @author blue
 *
 */
public class GCMIntentService extends GCMBaseIntentService {
	//////////////////////////////////////////////////////////////////////////////////////////////////////
	// 변수	

	private static final String TAG = "GCMIntentService";
	public static String userId = "";
	public static int count = 0;

	ChatRoomActivity chatRoomActivity = (ChatRoomActivity)ChatRoomActivity.chatRoomActivity;			// 종료시 더미도 함께 종료 시키기 위함

	// 진동
	Vibrator Vi;	//  진동
	int vibrateCnt = 3;

	// 서버 통신 관련
	Boolean dontTwice = true;
	PushChatRest pushChatRest = new PushChatRest();
	Boolean loading = false;
	// 통신 결과
	String callResult = "";	// 서버 호출 결과
	String tempstr = "";


	// 채팅방정보
	String message = "";
	String receivedChatRoomId = "";
	String receivedChatRoomOwner = "";

	// GCM
	String regIdGCM = "";
	Context localContext;
	String regResult="";


	// 설정 저장소  
	SharedPreferences sharedPrefCustom;
	String savedGCMId = "";
	String savedGCMUserId = "";

	///////////////////////////////////////////////////////////////////////////////////////////////////////////////

	public GCMIntentService() {
		super(SENDER_ID);
	}

	/**
	 * onRegistered
	 *  gcm 등록되면 비동기로 서버에 업데이트한다
	 *
	 * @param context
	 * @param registrationId
	 * @return
	 */
	@Override
	public void onRegistered(Context context, String registrationId) {
		Vi= (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);

		// prefs
		sharedPrefCustom = getSharedPreferences(CommonConstant.prefName,
				Context.MODE_WORLD_READABLE | Context.MODE_WORLD_WRITEABLE);
		savedGCMId = sharedPrefCustom.getString("savedGCMId", "");	
		savedGCMUserId = sharedPrefCustom.getString("savedGCMUserId", "");	
		userId = sharedPrefCustom.getString("userId", "");

		//			Log.d(TAG,"registrationId::"+registrationId);
		if(dontTwice){			// 한번
//			if(!( savedGCMId.equals(registrationId)&&savedGCMUserId.equals(userId))){		// 다를때만. (저장된 아이디까지) - 무조건
				regIdGCM = registrationId;
				new backgroundThreadUpdateMyGCMtoServer().execute();	// 서버에 GCM 아이디 저장	
				localContext = context;
				dontTwice = false;
//			}else{
//				Log.d(TAG,"GCM ID not changed");
//			}
		}
	}

	@Override
	protected void onUnregistered(Context context, String registrationId) {
		Log.i(TAG, "Device unregistered");
	}

	/**
	 * onMessage
	 *  서버에서 푸시가 오면 사용자에게 노티를 준다
	 *
	 * @param context
	 * @param intent
	 * @return
	 */
	@Override		// GCM 서비스 에서 온 메시지 받은거.
	protected void onMessage(Context context, Intent intent) {
		Log.i(TAG, "Received message");
		Vi= (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
		Log.d(TAG,"getExtras ::"+intent.getExtras());				

		// 받은 데이터 분리시키기
		String[] messages = intent.getStringExtra("MESSAGE").split(":");
		if(messages.length>0){
			message = messages[0];
		}
		if(messages.length>1){
			receivedChatRoomId = messages[1];
		}
		if(messages.length>2){
			receivedChatRoomOwner = messages[2];
		}

		Log.d(TAG,"message::"+message);
		Log.d(TAG,"receivedChatRoomId::"+receivedChatRoomId);
		Log.d(TAG,"receivedChatRoomOwner::"+receivedChatRoomOwner);
		Log.i(TAG, "Received message of onMessage():"+intent.getStringExtra("MESSAGE"));		

		// notifies user
		generateNotification(context, message, receivedChatRoomId, receivedChatRoomOwner);	// 추가 작업. 
	}

	@Override
	protected void onDeletedMessages(Context context, int total) {
		Log.i(TAG, "Received deleted messages notification");
	}

	@Override
	public void onError(Context context, String errorId) {
		Log.i(TAG, "Received error: " + errorId);
	}

	@Override
	protected boolean onRecoverableError(Context context, String errorId) {
		Log.i(TAG, "Received recoverable error: " + errorId);
		return super.onRecoverableError(context, errorId);
	}

	/**
	 * generateNotification
	 * Issues a notification to inform the user that server has sent a message.
	 * @param context
	 * @param message
	 * @return
	 */
	private  void generateNotification(Context context, String message, String receivedChatRoomId, String receivedChatRoomOwner) {

		//			// 예외처리.
		//			if(CommonConstant.appRunningYn==null){
		//				CommonConstant.appRunningYn = false;
		//			}
		//			if(CommonConstant.chatRoomUsingYn==null){
		//				CommonConstant.chatRoomUsingYn = false;
		//			}
		//			if(CommonConstant.currentChatRoomId==null){
		//				CommonConstant.currentChatRoomId = "";
		//			}
		//			if(CommonConstant.currentChatRoomOwner==null){
		//				CommonConstant.currentChatRoomOwner = "";
		//			}

		sharedPrefCustom = getSharedPreferences(CommonConstant.prefName,
				Context.MODE_WORLD_READABLE | Context.MODE_WORLD_WRITEABLE);

		Boolean appRunningYn = sharedPrefCustom.getBoolean("appRunningYn", false);
		Boolean chatRoomUsingYn = sharedPrefCustom.getBoolean("chatRoomUsingYn", false);
		String currentChatRoomId = sharedPrefCustom.getString("currentChatRoomId", "");
		String currentChatRoomOwner = sharedPrefCustom.getString("currentChatRoomOwner", "");


		// 실행중인지 확인.
		isRunningProcess(this, CommonConstant.packageNames);
		if(appRunningYn==false){
			//실행중이 아님 -> 더미로 데이터 전달.   
			Log.d(TAG, "not running");
			passDataToDummyActivity(context, message, receivedChatRoomId, receivedChatRoomOwner);
		}else if(count<2 && appRunningYn){	// 실행중
			Log.d(TAG, "running");

			// 채팅방에 있는지 확인
			if(chatRoomUsingYn){	// 현재 채팅방에 있음
				Log.d(TAG, "in chat room");

				// 동일한 채팅방인지 확인. 방번호와 방장 아이디이용.
				if(receivedChatRoomId.equals(currentChatRoomId) && receivedChatRoomOwner.equals(currentChatRoomOwner)){	// 동일한 채팅방
					Log.d(TAG, "same chat room");

					//						// 동일 방에 있을때 업데이트 호출.
					chatRoomActivity.callRefresh();

				}else{	// 다른 채팅방에 있을때 -> 노티 처리 액티비티로 데이터 전달
					Log.d(TAG, "other chat room");
					passDataToDummyActivity(context, message, receivedChatRoomId, receivedChatRoomOwner);	// *** 
				}                
			}else{		// 채팅방에 없을때 -> 노티 처리 액티비티로 데이터 전달 
				Log.d(TAG, "not chat room");
				passDataToDummyActivity(context, message, receivedChatRoomId, receivedChatRoomOwner);
			}
		}else{	// 실행중이 아님 -> 노티 처리 액티비티로 데이터 전달.   
			Log.d(TAG, "not running");
			passDataToDummyActivity(context, message, receivedChatRoomId, receivedChatRoomOwner);
		}	
	}

	/**
	 * 더미 액티비티로 데이터를 전달하는 노티를 생성한다.
	 */
	public void passDataToDummyActivity(Context context, String message, String receivedChatRoomId, String receivedChatRoomOwner){
		//			int icon = R.drawable.ic_launcher;
		vibrateOneTimes();	
		Log.d(TAG,"message::"+message);
		// 보여줄 메시지 결정
		String contents = "";
		if(message.equals("NEW_MESSAGE")){		
			contents =  getString(R.string.you_got_new_message);			
		}else if(message.equals("NEW_CHAT")){
			contents =  getString(R.string.you_got_invited_chat_room);
		}else{
			contents =  message;		
		}

		///////////////////////
		Intent notificationIntent = new Intent(context, NotiTouchActionControlActivity.class);	// *** 
		// 데이터 전달	 *** 
		sharedPrefCustom = getSharedPreferences(CommonConstant.prefName,
				Context.MODE_WORLD_READABLE | Context.MODE_WORLD_WRITEABLE);
		userId = sharedPrefCustom.getString("userId", "");
		Log.d(TAG,"notificationIntent userId:"+userId);
		notificationIntent.putExtra("RunMode", message);						 
		notificationIntent.putExtra("receivedUserId", userId);						 
		notificationIntent.putExtra("chatRoomId", receivedChatRoomId);				 		
		notificationIntent.putExtra("chatRoomOwner", receivedChatRoomOwner);	

		// 공통부
		PendingIntent contentIntent = PendingIntent.getActivity(context,
				0, notificationIntent,
				PendingIntent.FLAG_CANCEL_CURRENT);
		NotificationManager nm = (NotificationManager) context
		.getSystemService(Context.NOTIFICATION_SERVICE);
		Resources res = context.getResources();
		Builder builder = new Builder(context);
		builder.setContentIntent(contentIntent)
		.setSmallIcon(R.drawable.ic_launcher)		// 우측 하단 작은 이미지.. -- 주석하니까 안나옴
		.setLargeIcon(BitmapFactory.decodeResource(res, R.drawable.ic_launcher))		// 왼쪽 왕큰 이미지
		.setTicker(res.getString(R.string.app_name))
		.setWhen(System.currentTimeMillis())
		.setAutoCancel(true)
		.setContentTitle(res.getString(R.string.app_name))
		.setContentText(contents);	// *** 
		Notification n = builder.build();
		nm.notify(0, n);

	}

	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////	
	// 비동기

	/**
	 * backgroundThreadUpdateMyGCMtoServer
	 * 비동기    GCM 아이디 업뎃 호출  -- 서버에 gcm 아이디 업뎃
	 * @author blue
	 *
	 */
	public class backgroundThreadUpdateMyGCMtoServer extends AsyncTask<Void, Void, Void>{
		@Override protected void onPostExecute(Void result) {  
		} 
		@Override protected void onPreExecute() {  
		} 
		@Override protected Void doInBackground(Void... params) {  
			Log.d(TAG,"backgroundThreadUpdateMyGCMtoServer");
			if(userId==null || userId.length()<1){
				// 아이디 없으면 업데이트 하지 않음
			}else{		
				// 파라미터 셋팅
				PushChatMember pushChatMemberParam = new PushChatMember();
				pushChatMemberParam.setMemberId(userId);
				pushChatMemberParam.setRegistrationId(regIdGCM);
				//					ChatMember chatMember = new ChatMember();
				//					chatMember.setMemberId(userId);
				//					chatMember.setRegistrationId(regIdGCM);
				// 서버 메소드 호출
				callResult = pushChatRest.RestUpdateRegistrationId(pushChatMemberParam);
				// 결과 처리
				if(callResult.equals("SUCCESS")){				//  성공
					Log.i(TAG, "S to update GCM ID to server");
					saveGCMIdToPref();	// 서버에 성공적으로 저장되면 설정에도 저장한다.
				}else{														//  실패
					Log.i(TAG, "F to update GCM ID to server");
				}
			}
			return null; 
		}
	}
	/**
	 * GCM ID 를 pref 설정에 저장한다.
	 */
	public void saveGCMIdToPref(){
		SharedPreferences.Editor updatesavedGCMId =   sharedPrefCustom.edit();
		updatesavedGCMId.putString("savedGCMId", regIdGCM);		// GCM ID저장
		updatesavedGCMId.putString("savedGCMUserId", userId);		// ID저장
		updatesavedGCMId.commit();
	}

	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////	
	/**
	 * isRunningProcess
	 *  중복 실행 방지를 위해 카운팅 체크를 한다.
	 *
	 * @param context
	 * @param packageName
	 * @return isRunning
	 */
	public static boolean isRunningProcess(Context context, String packageName) {
		count = 0;
		boolean isRunning = false;
		ActivityManager actMng = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);   
		List<RunningAppProcessInfo> list = actMng.getRunningAppProcesses();
		for(RunningAppProcessInfo rap : list) {
			if(rap.processName.equals(packageName)) {
				isRunning = true;
				count= count+1;		// 실행중인  수 (중복 실행 방지 용)
				Log.d("Log","count:"+count);
				break;
			}
		}
		return isRunning;
	}


	public Context returnThis(){
		return this;
	}

	// 진동 1
	public void vibrateOneTimes(){
		new Thread(
				new Runnable(){
					public void run(){
						try {
							Vi.vibrate(1000);
							Thread.sleep(2000);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
		).start();
	}
	// 진동 3
	public void vibrateNTimes(){
		new Thread(
				new Runnable(){
					public void run(){
						try {
							for(int i=0; i<vibrateCnt; i++){
								Vi.vibrate(1000);
								Thread.sleep(2000);
							}
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
		).start();
	}
}
